package xj.graph2d;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.print.PageFormat;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.swing.JOptionPane;

public class SimpleDrawView 
  extends View 
  implements DrawShapeConstants {

  public SimpleDrawView(SimpleDrawDocument doc) {
    this(doc, null, null, null);
  }

  protected SimpleDrawView(SimpleDrawDocument doc, 
			   DrawAttr attr,
			   ArrowAttr headArrowAttr, 
			   ArrowAttr tailArrowAttr) {
    super(doc);
    sdoc = doc;
    if (attr != null) {
      this.attr = attr;
    } else {
      this.attr = new DrawAttr();
    }
    if (headArrowAttr != null) {
      this.headArrowAttr = headArrowAttr;
    } else {
      this.headArrowAttr = new ArrowAttr();
    }
    if (tailArrowAttr != null) {
      this.tailArrowAttr = tailArrowAttr;
    } else {
      this.tailArrowAttr = new ArrowAttr();
    }

    initThumbNail();
  }

  public void setSimpleDrawDocument(SimpleDrawDocument doc) {
    super.setDocument(doc);
    String name = doc.getName();
    // setTitle(name);
    initThumbNail();
  }

  @Override
  protected void initThumbNail() {
    // Rectangle2D rect = doc.getBounds();
    Rectangle2D rect = getVirtualCanvasRectangle();
    // setVirtualCanvasRectangle(doc.getBounds());

    // float f = 0.0675f;
    float f = 0.25f;
    int w = (int) Math.max(rect.getWidth() * f, 100);
    int h = (int) Math.max(rect.getHeight() * f, 100);
    setThumbNail(w, h, f);
  }

  public SimpleDrawDocument getSimpleDrawDocument() {
    return sdoc;
  }

  public void paintShape(Graphics2D g2, DrawShape shape) {
    paintShape(g2, shape, false);
  }

  public void paintShape(Graphics2D g2, DrawShape shape, boolean printing) {
    if (shape != null) {
      DrawShape selected = sdoc.getSelectedShape();
      shape.drawShape(g2, (!printing && shape == selected) ? DRAW_SELECTED
		      : DRAW_DEFAULT);
    }
  }

  @Override
  public void paintCanvas(Graphics2D g2, 
			  Rectangle2D rect, 
			  boolean printing,
			  boolean thumbnail) {
    if (debug) {
      System.out.println("SimpleDrawView.paintCanvas(): rect=" + rect);
    }
    
    if (sdoc != null) {
      DrawShape selected = null;
      Group group = sdoc.getGroup();
      if (!printing) {
	selected = sdoc.getSelectedShape();
	if (!thumbnail) {
	  paintBackgroundAndGrid(g2, rect);
	}

	if (group != null && group.isVisible()) {
	  group.drawShape(g2, (group == selected ? DRAW_SELECTED : DRAW_DEFAULT));
	}
      } else {
	if (group != null && group.isVisible()) {
	  group.drawShape(g2, DRAW_DEFAULT);
	}
      }

      int n = sdoc.count();

      if (debug) {
	System.out.println("SimpleDrawView.paintCanvas():selected=" + selected);
	System.out.println("SimpleDrawView.paintCanvas():n=" + n);
      }
      for (int i = 0; i < n; i++) {
	DrawShape shape = sdoc.get(i);
	if (debug) {
	  System.out.println("SimpleDrawView.paintCanvas(): shape[" + i + 
			     "].isVisible=" + shape.isVisible());
	}

	if (shape != null && shape.isVisible()) {
	  boolean visible = true;
	  /*
	   * CompoundDrawShape container = shape.getContainer(); if
	   * (container != null && container == group) { visible = false; //
	   * do not draw the shapes in the group twice. }
	   */
	  if (visible && 
	      !thumbnail && 
	      rect != null) {
	    Rectangle2D r = shape.getFrameBounds();
	    if (debug) {
	      System.out.println("SimpleDrawView.paintCanvas(): shape[" + i + "]:" + shape);
	      /*
	       * System.out.println("SimpleDrawView.paintCanvas(): shape[" + i +
	       * "].bounds=" + r + " penSize=" + shape.getDrawAttr().penSize);
	       */
	      System.out.println("SimpleDrawView.paintCanvas(): shape[" + i + 
				 "].class=" + shape.getClass().getName());
	    }
	    double x = r.getX();
	    double y = r.getY();
	    double w = r.getWidth();
	    double h = r.getHeight();
	    if (w == 0.0 && h == 0.0 || 
		!rect.intersects(x, y, w + 1, h + 1)) {
	      visible = false;
	    }
	  }
	  if (visible) {
	    if (debug) {
	      System.out.println("SimpleDrawView.paintCanvas(): shape[" + i + 
				 "] selected=" + (shape == selected) + 
				 " isZeroSize=" + shape.isZeroSize());
	    }
	    if (printing) {
	      if (!shape.isZeroSize()) {
		shape.drawShape(g2, DRAW_PRINT);
	      }
	    } else {
	      /*
	       * if (sdoc.inSelectionSet(shape)) {
	       * DrawingUtilities.drawGroupFrame(g2, shape.getBounds(), true); }
	       */
	      shape.drawShape(g2, selected, sdoc.getSelectionSet());
	    }
	  }
	}
      }
    }
  }

  public DrawAttr getDrawAttr() {
    return attr;
  }

  public void setDrawAttr(DrawAttr attr) {
    this.attr = attr;
  }

  public ArrowAttr getHeadArrowAttr() {
    return headArrowAttr;
  }

  public void setHeadArrowAttr(ArrowAttr headArrowAttr) {
    this.headArrowAttr = headArrowAttr;
  }

  public ArrowAttr getTailArrowAttr() {
    return tailArrowAttr;
  }

  public void setTailArrowAttr(ArrowAttr tailArrowAttr) {
    this.tailArrowAttr = tailArrowAttr;
  }

  public boolean isUnderlined() {
    if (attr != null) {
      return attr.isUnderlined();
    }
    return false;
  }

  public void setUnderlined(boolean underlined) {
    if (attr != null) {
      attr.setUnderlined(underlined);
    }
  }

  public void setBoldFont(boolean bold) {
    if (attr != null) {
      attr.setBoldFont(bold);
    }
  }

  public void setItalicFont(boolean italic) {
    if (attr != null) {
      attr.setItalicFont(italic);
    }
  }

  public int getAlignment() {
    return alignment;
  }

  public void setAlignment(int alignment) {
    this.alignment = alignment;
  }

  @Override
  public String toString() {
    return "Text Box";
  }

  public String getDocumentName() {
    if (sdoc != null) {
      return sdoc.getName();
    }
    return null;
  }

  protected PrintManager printManager = null;

  @Override
  public int print(Graphics g, PageFormat pf, int pageIndex) {
    if (printManager == null) {
      doPageSetup();
    }
    if (printManager != null) {
      return printManager.printPage(g, pageIndex);
    } else {
      return NO_SUCH_PAGE;
    }
  }

  public void doPrintPreview() {
    if (printManager == null) {
      doPageSetup();
    }
    if (printManager != null) {
      printManager.showPreviewDialog();
    } else {
      displayHelpMessage("PreviewFail.message");
    }
  }

  public void doPrint() {
    if (printManager == null) {
      // printer = PrinterJob.getPrinterJob();
      // page = printer.defaultPage();
      doPageSetup();
    } else {
      printManager.reset();
    }
    printer.setPrintable(this, page);

    if (printer.printDialog()) {
      try {
	printer.print();
      } catch (PrinterException e) {
	JOptionPane.showMessageDialog(this, 
				      "ERROR: Printing Failed;",
				      "Print error", 
				      JOptionPane.ERROR_MESSAGE);
      }
    }
  }

  // Displays the page setup dialog and updates PageFormat info
  public void doPageSetup() {
    try {
      if (printer == null) {
	printer = PrinterJob.getPrinterJob();
	page = printer.defaultPage();
      }
      page = printer.pageDialog(page);
      printManager = new PrintManager(this, page);
    } catch (PrinterException e) {
      JOptionPane.showMessageDialog(this, 
				    "ERROR: Printing Failed;",
				    "Print error", 
				    JOptionPane.ERROR_MESSAGE);
    } catch (Exception e) {
      JOptionPane.showMessageDialog(this, 
				    "ERROR: Printing Failed;",
				    "Print error", 
				    JOptionPane.ERROR_MESSAGE);
      e.printStackTrace(System.err);
    }
  }

  protected SimpleDrawDocument sdoc;

  protected DrawAttr attr;

  protected ArrowAttr headArrowAttr;

  protected ArrowAttr tailArrowAttr;

  protected int alignment;

  // Printing constants and variables
  public final int ONE_PAGE = 0;

  public final int ALL_PAGES = 1;

  protected int printMode = ONE_PAGE;

  protected PageFormat page = null;

  protected PrinterJob printer = null;

  protected static boolean debug = false;

}
